<?php

namespace app\admin\model\tongcheng;

use addons\tongcheng\enum\DeliveryOrderStatus;
use addons\tongcheng\enum\DeliveryRefundStatus;
use addons\tongcheng\model\BaseModel;


class DeliveryOrderModel extends BaseModel
{
    // 表名
    protected $name = 'tongcheng_delivery_order';

    // 自动写入时间戳字段
    protected $autoWriteTimestamp = 'integer';

    // 定义时间戳字段名
    protected $createTime = 'createtime';
    protected $updateTime = 'updatetime';
    protected $deleteTime = false;

    // 追加属性
    protected $append = [
        'type_text',
        'appoint_time_text',
        'status_text',
        'pay_time_text',
        'receive_time_text',
        'arrive_time_text',
        'delivery_time_text',
        'complete_time_text',
        'expire_complete_time_text',
        'cancel_time_text',
        'cancel_role_text',
        'refund_time_text',
        'createtime_text',
        'refund_status_text',
        'buttons',
        'refund_buttons',
        'expire_pay_timer',
        'expire_receive_timer',
        'expire_complete_timer',
    ];


    public function getTypeList()
    {
        // return ModuleType::getValueDescription();
        return [
            'CITY' => '城际',
            'HIT'  => '打车',
            '代驾' => '代驾',
            'BUY'  => '帮我买',
            'SEND' => '帮我送',
            'TAKE' => '帮我取',
            'WAN'  => '万能帮',
            '1V1'  => '1对1专送',
        ];
    }

    public function getStatusList()
    {
        return [
            DeliveryOrderStatus::UNPAID     => '待支付',
            DeliveryOrderStatus::PAID       => '待接单',
            DeliveryOrderStatus::RECEIVED   => '已接单',
            DeliveryOrderStatus::ARRIVED    => '到达上车点',
            DeliveryOrderStatus::DELIVERING => '行程中',
            DeliveryOrderStatus::COMPLETED  => '已完成',
            DeliveryOrderStatus::CANCELLED  => '订单取消',
            DeliveryOrderStatus::REFUNDED   => '退款取消',
        ];
        // return DeliveryOrderStatus::getValueDescription();
    }

    public function getRefundStatusList()
    {
        return [
            DeliveryRefundStatus::WAIT     => '',
            DeliveryRefundStatus::ACCEPT   => '已同意退款',
            DeliveryRefundStatus::REJECT   => '已驳回退款',
            DeliveryRefundStatus::UNHANDLE => '退款待处理',
        ];
    }

    public function getCancelRoleList()
    {
        return [
            'CUSTOMER' => '顾客',
            'SYSTEM'   => '系统',
            'ADMIN'    => '管理员',
            'RIDER'    => '骑手',
        ];
        // return UserRole::getValueDescription();
        // return ['CUSTOMER' => __('Customer'), 'SYSTEM' => __('System'), 'RIDER' => __('Rider')];
    }


    public function getTypeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['type']) ? $data['type'] : '');
        $list  = $this->getTypeList();
        return isset($list[$value]) ? $list[$value] : '';
    }


    public function getAppointTimeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['appoint_time']) ? $data['appoint_time'] : '');
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
    }


    public function getStatusTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['status']) ? $data['status'] : '');
        // $list  = $this->getStatusList();
        // return isset($list[$value]) ? $list[$value] : '';
        return $this->getStatus($value, 'text');
    }


    public function getRefundStatusTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['refund_status']) ? $data['refund_status'] : '');
        // $list  = $this->getStatusList();
        // return isset($list[$value]) ? $list[$value] : '';
        return $this->getRefundStatus($value, 'text');
    }


    public function getPayTimeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['pay_time']) ? $data['pay_time'] : '');
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
    }


    public function getReceiveTimeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['receive_time']) ? $data['receive_time'] : '');
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
    }


    public function getArriveTimeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['arrive_time']) ? $data['arrive_time'] : '');
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
    }


    public function getDeliveryTimeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['delivery_time']) ? $data['delivery_time'] : '');
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
    }


    public function getCompleteTimeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['complete_time']) ? $data['complete_time'] : '');
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
    }


    public function getExpireCompleteTimeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['expire_complete_time']) ? $data['expire_complete_time'] : '');
        return is_numeric($value) && $value > 0 ? date("Y-m-d H:i:s", $value) : '-';
    }


    public function getCancelTimeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['cancel_time']) ? $data['cancel_time'] : '');
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
    }

    public function getCreatetimeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['createtime']) ? $data['createtime'] : '');
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
    }


    public function getCancelRoleTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['cancel_role']) ? $data['cancel_role'] : '');
        $list  = $this->getCancelRoleList();
        return isset($list[$value]) ? $list[$value] : '';
    }


    public function getRefundTimeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['refund_time']) ? $data['refund_time'] : '');
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
    }

    public function getExpirePayTimerAttr($value, $data)
    {
        $status = $data['status'] ?? 0;
        if ($status != DeliveryOrderStatus::UNPAID) {
            return 0;
        }
        $value = $value ? $value : (isset($data['expire_pay_time']) ? $data['expire_pay_time'] : '');
        return $value ? $value - time() : 0;
    }

    public function getExpireReceiveTimerAttr($value, $data)
    {
        $status = $data['status'] ?? 0;
        if ($status != DeliveryOrderStatus::PAID) {
            return 0;
        }
        $value = $value ? $value : (isset($data['expire_receive_time']) ? $data['expire_receive_time'] : '');
        return $value ? $value - time() : 0;
    }

    public function getExpireCompleteTimerAttr($value, $data)
    {
        if (!($data['expire_complete_time'] ?? 0)) {
            return 0;
        }

        $status = $data['status'] ?? 0;
        if (!($status >= DeliveryOrderStatus::RECEIVED && $status < DeliveryOrderStatus::COMPLETED)) {
            return 0;
        }

        $value = $value ?: ($data['expire_complete_time'] ?? '');
        return $value ? max($value - time(), 0) : 0;
    }

    protected function setAppointTimeAttr($value)
    {
        return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
    }

    protected function setPayTimeAttr($value)
    {
        return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
    }

    protected function setReceiveTimeAttr($value)
    {
        return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
    }

    protected function setArriveTimeAttr($value)
    {
        return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
    }

    protected function setDeliveryTimeAttr($value)
    {
        return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
    }

    protected function setCompleteTimeAttr($value)
    {
        return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
    }

    protected function setCancelTimeAttr($value)
    {
        return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
    }

    protected function setRefundTimeAttr($value)
    {
        return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
    }

    public function getButtonsAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['status']) ? $data['status'] : '');
        return $this->getStatus($value, 'buttons', $data['refund_status'] ?? 0);
    }

    public function getRefundButtonsAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['refund_status']) ? $data['refund_status'] : '');
        return $this->getRefundStatus($value, 'buttons');
    }

    public function user()
    {
        return $this->belongsTo('app\admin\model\User', 'user_id', 'id', [], 'LEFT')->setEagerlyType(0);
    }


    public function zone()
    {
        return $this->belongsTo(ZoneModel::class, 'zone_id', 'id', [], 'LEFT')->setEagerlyType(0);
    }


    public function module()
    {
        return $this->belongsTo(ModuleModel::class, 'module_id', 'id', [], 'LEFT')->setEagerlyType(0);
    }


    public function rider()
    {
        return $this->belongsTo(RiderModel::class, 'rider_id', 'id', [], 'LEFT')->setEagerlyType(0);
    }

    public function fees()
    {
        return $this->hasOne(DeliveryOrderFeeModel::class, 'order_id');
    }

    public function refund()
    {
        return $this->hasOne(DeliveryOrderRefundModel::class, 'order_id')->order('id desc');
    }

    public function actions()
    {
        return $this->hasMany(DeliveryOrderActionModel::class, 'order_id');
    }

    /**
     * 获取配送订单状态
     * @param int    $status
     * @param string $type
     * @param int    $refund_status
     * @return array|mixed|string[]|void
     */
    protected function getStatus($status, $type, $refund_status = 0)
    {
        if ($type == 'text') {
            $statusList = $this->getStatusList();
            return $statusList[$status];
        } else if ($type == 'buttons') {
            switch ($status) {
                case DeliveryOrderStatus::UNPAID:
                    return [
                        'cancel' => '取消订单',
                        'pay'    => '去支付',
                    ];

                case DeliveryOrderStatus::PAID:
                    return [
                        'refund' => '申请退款',
                    ];

                case DeliveryOrderStatus::RECEIVED:
                    // 无申请退款或已拒绝
                    if (in_array($refund_status, [DeliveryRefundStatus::WAIT, DeliveryRefundStatus::REJECT])) {
                        return [
                            'refund' => '申请退款',
                        ];
                    }

                    return null;

                case DeliveryOrderStatus::ARRIVED:
                case DeliveryOrderStatus::DELIVERING:
                case DeliveryOrderStatus::COMPLETED:
                case DeliveryOrderStatus::CANCELLED:
                default:
                    return null;
                // break;
                // return [];
            }
        }
    }

    /**
     * 获取配送订单退款状态
     * @param $status
     * @param $type
     * @return array|mixed|string[]|void
     */
    protected function getRefundStatus($status, $type)
    {
        if ($type == 'text') {
            $statusList = $this->getRefundStatusList();
            return $statusList[$status];
        } else if ($type == 'buttons') {
            switch ($status) {
                case DeliveryRefundStatus::UNHANDLE:
                    return [
                        'refund_accept' => '同意退款',
                        'refund_reject' => '拒绝退款',
                    ];

                default:
                    break;
                // return [];
            }
        }
    }

    /**
     * 获取订单
     * @param $id
     * @param $with
     * @param $user_id
     * @param $lock
     * @return array|bool|\PDOStatement|string|\think\Model|null
     */
    public static function getById($id, $with = [], $user_id = 0, $lock = false)
    {
        $query = self::with($with)->where('id', $id);
        if ($user_id) {
            $query->where('user_id', $user_id);
        }
        if ($lock) {
            $query->lock(true);
        }
        return $query->find();
    }

    /**
     * 计算配送费用（买家应付）
     * @param $fees
     * @return float
     */
    public static function calcDeliveryFee($fees)
    {
        $base_fee      = $fees['base_fee'] ?? 0;
        $tip_fee       = $fees['tip_fee'] ?? 0;
        $advance_fee   = $fees['advance_fee'] ?? 0;
        $range_fee     = $fees['range_fee'] ?? 0;
        $weight_fee    = $fees['weight_fee'] ?? 0;
        $surcharge_fee = $fees['surcharge_fee'] ?? 0;
        $insure_fee    = 0;//$fees['insure_fee'] ?? 0;

        // if (input('chao')) {
        //     dd($base_fee, $tip_fee, $advance_fee, $range_fee, $weight_fee, $surcharge_fee);
        // }

        return tongcheng_calc_fee('+', $base_fee, $tip_fee, $advance_fee, $range_fee, $weight_fee, $surcharge_fee, $insure_fee);
    }

    /**
     * 计算骑手实收配送费用（抽佣）
     * @param $orders
     * @param $zone_delivery_fee_rate
     * @return void
     */
    public static function calcOrderRiderDeliveryFee(&$orders, $zone_delivery_fee_rate)
    {
        $zone_delivery_fee_rate = $zone_delivery_fee_rate ? $zone_delivery_fee_rate / 100 : 0;

        // 单模型
        if (isset($orders['id'])) {
            if (empty($orders['fee'])) {
                return;
            }

            $orders['fee']['rider_delivery_fee'] = tongcheng_calc_fee('*', $orders['fee']['no_rate_delivery_fee'], $zone_delivery_fee_rate);
        } else {
            // 多模型
            foreach ($orders as &$order) {
                if (empty($order['fee'])) {
                    continue;
                }

                $order['fee']['rider_delivery_fee'] = tongcheng_calc_fee('*', $order['fee']['no_rate_delivery_fee'], $zone_delivery_fee_rate);
            }
        }
    }


}
